#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Projet CellMates
# Judith ROBSON
# Roxane LEVY
# Ludovic JURADO

import Widgets
import Globals
from PySide.QtCore import *
from PySide.QtGui import *

""" Classe "OPTIONS".
	Elle gère toutes les options de configuration nécessaires à l'exécution de l'automate.

Options des états :
- choix du nombre d'états
- choix des couleurs des états
- choix des densités de couleur sur la grille
- possibilité de générer des densités aléatoires

Options de voisinage :
- affichage du voisinage
- choix de la taille du voisinage
- choix du type de voisinage
- possibilité de générer un voisinage aléatoire

Options de grille :
- choix du type de grille
- choix de la taille de la grille
- possibilité de générer une grille monocolore ou aléatoire

Options de règles :
- affichage des règles
- choix des règles
- possibilité de générer des règles aléatoires

Options de défilement :
- affichage de l'étape courante
- choix de la vitesse de défilement
- boutons de défilement

Option de génération aléatoire globale :
- bouton "générer" """


class Options(QWidget) :

	# Fonction d'initialisation
	def __init__(self, parent = None) :
		QWidget.__init__(self, parent)
		options = QVBoxLayout()
		self.formulaire = QFormLayout()

		self.setJDLM()
		self.setNombreEtats()
		self.setCouleurs()
		self.setDensite()
		self.setTailleVoisinage()
		self.setVoisinage()
		self.setTypeGrille()
		self.setNombreCellules()
		self.setTypeRemplissage()
		self.setRegles()
		self.setVitesse()

		options.addLayout(self.formulaire)
		self.fin = QHBoxLayout()

		self.setEtapes()

		options.addLayout(self.fin)
		self.setLayout(options)


	# Active mini jeu basé sur le Jeu de la Vie
	def setJDLM(self) :
		groupeJDLM = QGroupBox()
		layoutVJDLM = QVBoxLayout()
		layoutHJDLM = QHBoxLayout()

		self.activeJDLM = QPushButton(self.trUtf8("Lancer/Arrêter"))
		self.activeJDLM.setCheckable(True)
		self.activeJDLM.setChecked(False)
		self.activeJDLM.setToolTip(self.trUtf8("Lance un mini jeu exploitant les règles du jeu de la vie.\nA chaque étape, chaque cellule naissante est comptabilisée et vient augmenter le score du joueur\n(plus ou moins en fonction de la difficulté choisie).\nLe but du jeu est d'engranger un maximum de points.\nLe joueur peut, avec le clic droit, influencer le déroulement des étapes en amenant une cellule à la vie.\nEn choisissant bien les cellules qu'il anime, le joueur peut donc engendrer une explosion du nombre de cellules vivantes,\ncréer des oscillateurs qui lui rapporteront des points de manière constante... ou au contraire accélérer le processus de mort !\nSi le nombre d'étapes maximum est atteint ou si toutes les cellules sont mortes, la partie se termine."))
		layoutHJDLM.addWidget(self.activeJDLM)

		self.valDifficulte = QSpinBox()
		self.valDifficulte.setMinimum(1)
		self.valDifficulte.setMaximum(10)
		self.valDifficulte.setPrefix("Diff : ")
		self.valDifficulte.setToolTip(self.trUtf8("Difficulté de la partie"))
		layoutHJDLM.addWidget(self.valDifficulte)

		self.valLimEtape = QSpinBox()
		self.valLimEtape.setMinimum(100)
		self.valLimEtape.setMaximum(10000)
		self.valLimEtape.setPrefix("Limite : ")
		self.valLimEtape.setToolTip(self.trUtf8("Nombre limite d'étapes avant la fin de la partie"))
		layoutHJDLM.addWidget(self.valLimEtape)

		self.scoreTitreJDLM = QLabel(self.trUtf8("Meilleur Score (Difficulté) / Score Actuel :"))
		self.scoreJDLM = QLabel()

		layoutVJDLM.addItem(layoutHJDLM)
		layoutVJDLM.addWidget(self.scoreTitreJDLM)
		layoutVJDLM.addWidget(self.scoreJDLM)

		groupeJDLM.setLayout(layoutVJDLM)
		self.formulaire.addRow(self.trUtf8("'Jeu de la Mort'"), groupeJDLM)


	# Création de la sélection du nombre d'états
	def setNombreEtats(self) :
		groupeNombreEtats = QGroupBox()
		nombreEtats = QHBoxLayout()
		self.etats = []
		self.etats.append(QRadioButton("2")) # 2 états
		self.etats.append(QRadioButton("3")) # 3 états
		self.etats.append(QRadioButton("4")) # 4 états
		self.etats.append(QRadioButton("5")) # 5 états

		for i in range(4) :
			self.etats[i].setToolTip(self.trUtf8("Sélectionne "+str(i+2)+" états pour l'automate"))
			nombreEtats.addWidget(self.etats[i]) # Attachement des boutons au formulaire

		groupeNombreEtats.setLayout(nombreEtats)
		self.formulaire.addRow(self.trUtf8("Nombre d'états"), groupeNombreEtats)


	# Création de la sélection de couleurs
	def setCouleurs(self) :
		groupeCouleurs = QGroupBox()
		couleurs = QHBoxLayout()
		self.couleur = []
		self.couleur.append(Widgets.ImageButton()) # Couleur de l'état 1
		self.couleur.append(Widgets.ImageButton()) # Couleur de l'état 2
		self.couleur.append(Widgets.ImageButton()) # Couleur de l'état 3
		self.couleur.append(Widgets.ImageButton()) # Couleur de l'état 4
		self.couleur.append(Widgets.ImageButton()) # Couleur de l'état 5

		for i in range(5) :
			self.couleur[i].setToolTip(self.trUtf8("Clique gauche : sélectionne cette couleur\nClique droit sur la grille : colore la cellule avec cette couleur\nDouble clique : change la couleur"))
			couleurs.addWidget(self.couleur[i]) # Attachement des boutons au formulaire

		groupeCouleurs.setLayout(couleurs)
		self.formulaire.addRow(self.trUtf8("Couleurs des états"), groupeCouleurs)


	# Création de la sélection de densités de couleurs (états)
	def setDensite(self) :
		groupeDensite = QGroupBox()
		densite = QHBoxLayout()
		self.eqDensite = QPushButton(self.trUtf8("Equilibrée")) # forcer l'équilibre des densités
		self.newDensite = QPushButton(self.trUtf8("Générer")) # Génération de densités
		self.densites = []
		self.densites.append(QSpinBox()) # Densité de l'état 1
		self.densites.append(QSpinBox()) # Densité de l'état 2
		self.densites.append(QSpinBox()) # Densité de l'état 3
		self.densites.append(QSpinBox()) # Densité de l'état 4
		self.densites.append(QSpinBox()) # Densité de l'état 5

		self.eqDensite.setCheckable(True)
		self.eqDensite.setChecked(False)
		self.eqDensite.setToolTip(self.trUtf8("Même proportion du nombre de cellules dans chaque état"))
		densite.addWidget(self.eqDensite)

		self.newDensite.setToolTip(self.trUtf8("Génère des densités pour les états actifs (aléatoires si 'Equilibrée' non coché)"))
		densite.addWidget(self.newDensite)

		for i in range(5) :
			self.densites[i].setToolTip(self.trUtf8("Choix de la densité pour l'état "+str(i+1)))
			self.densites[i].setAccelerated(True)
			densite.addWidget(self.densites[i]) # Attachement des boutons au formulaire

		groupeDensite.setLayout(densite)
		self.formulaire.addRow(self.trUtf8("Densité des états"), groupeDensite)


	# Création de la sélection du type de grille
	def setTypeGrille(self) :
		groupeGrille = QGroupBox()
		grille = QHBoxLayout()
		self.bornee = QRadioButton(self.trUtf8("Bornée")) # Choix d'une grille bornée
		self.toroidale = QRadioButton(self.trUtf8("Toroïdale")) # Choix d'une grille toroïdale

		self.bornee.setToolTip(self.trUtf8("Choix d'une grille bornée"))
		self.toroidale.setToolTip(self.trUtf8("Choix d'une grille toroïdale"))

		# Attachement des boutons au formulaire
		grille.addWidget(self.bornee)
		grille.addWidget(self.toroidale)
		groupeGrille.setLayout(grille)
		self.formulaire.addRow(self.trUtf8("Type de grille"), groupeGrille)


	# Création de la sélection de remplissage de la grille
	def setTypeRemplissage(self) :
		groupeRemplissage = QGroupBox()
		remplissage = QHBoxLayout()
		self.random = QPushButton(self.trUtf8("Aléatoire")) # Choix d'une grille aléatoire
		self.mono = QPushButton(self.trUtf8("Monocolore")) # Choix d'une grille monocolore

		self.random.setToolTip(self.trUtf8("Génère une grille aléatoire avec les densités sélectionnées"))
		self.mono.setToolTip(self.trUtf8("Génère une grille unie dans la couleur sélectionnée"))

		# Attachement des boutons au formulaire
		remplissage.addWidget(self.random)
		remplissage.addWidget(self.mono)
		groupeRemplissage.setLayout(remplissage)
		self.formulaire.addRow(self.trUtf8("Remplissage"), groupeRemplissage)


	# Création de la taille de la grille (en nombre de cellules/ligne et /colonne)
	def setNombreCellules(self) :
		groupeNombreCellules = QGroupBox()
		nombreCellules = QHBoxLayout()
		self.ligne = QSpinBox() # Choix du nombre de cellules par ligne
		ligneNom = QLabel(self.trUtf8("/ligne"))
		self.colonne = QSpinBox() # Choix du nombre de cellules par colonne
		colonneNom = QLabel(self.trUtf8("/colonne"))

		self.ligne.setAccelerated(True)
		self.ligne.setMinimum(2)
		self.ligne.setMaximum(100)
		self.ligne.setToolTip(self.trUtf8("Choix du nombre de lignes de la grille"))
		self.colonne.setAccelerated(True)
		self.colonne.setMinimum(2)
		self.colonne.setMaximum(100)
		self.colonne.setToolTip(self.trUtf8("Choix du nombre de colonnes de la grille"))

		# Attachement des boutons au formulaire
		nombreCellules.addWidget(self.ligne)
		nombreCellules.addWidget(ligneNom)
		nombreCellules.addWidget(self.colonne)
		nombreCellules.addWidget(colonneNom)
		groupeNombreCellules.setLayout(nombreCellules)
		self.formulaire.addRow(self.trUtf8("Nombre de cellules"), groupeNombreCellules)


	# Création de la sélection de taille de voisinage (pour l'état courant)
	def setTailleVoisinage(self) :
		groupeTailleVoisinage = QGroupBox()
		tailleVoisinage = QHBoxLayout()
		self.taille = []
		self.taille.append(QRadioButton("1")) # Choix d'un voisinage de taille 1
		self.taille.append(QRadioButton("2")) # Choix d'un voisinage de taille 2
		self.taille.append(QRadioButton("3")) # Choix d'un voisinage de taille 3

		for i in range(3) :
			self.taille[i].setToolTip(self.trUtf8("Choix d'un voisinage de taille "+str(i+1)+" pour l'état courant"))
			tailleVoisinage.addWidget(self.taille[i]) # Attachement des boutons au formulaire

		groupeTailleVoisinage.setLayout(tailleVoisinage)
		self.formulaire.addRow(self.trUtf8("Taille du voisinage"), groupeTailleVoisinage)


	# Création de la sélection de type de voisinage (pour l'état courant)
	def setVoisinage(self) :
		groupeVoisinage = QGroupBox()
		voisinage = QHBoxLayout()
		voisinageOptions = QVBoxLayout()
		voisinageSchema = QVBoxLayout()
		self.moore = QRadioButton(self.trUtf8("Moore")) # Voisinage de Moore
		self.vonNeumann = QRadioButton(self.trUtf8("Von Neumann")) # Voisinage de Von Neumann
		self.voisinagePerso = QRadioButton(self.trUtf8("Personnalisé")) # Voisinage personnalisable
		self.aleatoire = QPushButton(self.trUtf8("Aléatoire")) # Voisinage aléatoire
		self.nonTotalistique = QCheckBox(self.trUtf8("Voisinage non totalistique")) # Permet un voisinage non totalistique
		self.voisinageConfig = Widgets.Voisinage() # Affichage du voisinage courant
		voisinageConfigView = QGraphicsView(self.voisinageConfig)

		voisinageConfigView.setFixedSize(QSize(185, 185))
		voisinageConfigView.setAlignment(Qt.AlignCenter)

		self.moore.setToolTip(self.trUtf8("Choix d'un voisinage de Moore pour l'état courant"))
		self.vonNeumann.setToolTip(self.trUtf8("Choix d'un voisinage de Von Neumann pour l'état courant"))
		self.voisinagePerso.setToolTip(self.trUtf8("Choix d'un voisinage personnalisé pour l'état courant"))
		self.aleatoire.setToolTip(self.trUtf8("Génère un voisinage aléatoire pour l'état courant"))
		self.nonTotalistique.setToolTip(self.trUtf8("Autorise un voisinage non totalistique pour l'état courant"))

		# Attachement des boutons au formulaire
		voisinageOptions.addWidget(self.moore)
		voisinageOptions.addWidget(self.vonNeumann)
		voisinageOptions.addWidget(self.voisinagePerso)
		voisinageSchema.addWidget(voisinageConfigView)
		voisinageSchema.addWidget(self.aleatoire)
		voisinageSchema.addWidget(self.nonTotalistique)
		voisinage.addLayout(voisinageOptions)
		voisinage.addLayout(voisinageSchema)
		groupeVoisinage.setLayout(voisinage)
		self.formulaire.addRow(self.trUtf8("Type de voisinage"), groupeVoisinage)


	# Création de la sélection des règles
	def setRegles(self) :
		groupeRegles = QGroupBox()
		regles = QHBoxLayout()
		self.listeRegles = QTextEdit() # Affichage des règles
		reglesBoutons = QVBoxLayout()
		self.persoRegles = QPushButton(self.trUtf8("Personnalisé")) # Création de règles personnalisées
		self.randomRegles = QPushButton(self.trUtf8("Aléatoire")) # Génération de règles aléatoires
		spacer = QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding)

		self.listeRegles.setReadOnly(True)

		self.persoRegles.setToolTip(self.trUtf8("Choix de règles personnalisées"))
		self.randomRegles.setToolTip(self.trUtf8("Génère des règles aléatoires"))

		# Attachement des boutons au formulaire
		reglesBoutons.addWidget(self.persoRegles)
		reglesBoutons.addWidget(self.randomRegles)
		reglesBoutons.addSpacerItem(spacer)
		regles.addWidget(self.listeRegles)
		regles.addLayout(reglesBoutons)
		groupeRegles.setLayout(regles)
		self.formulaire.addRow(self.trUtf8("Règles"), groupeRegles)


	# Création du slider réglant la vitesse de défilement
	def setVitesse(self) :
		groupeVitesse = QGroupBox()
		vitesse = QHBoxLayout()
		vitesseMoins = QLabel(self.trUtf8("-"))
		self.vitesseSlider = QSlider() # Slider
		vitessePlus = QLabel(self.trUtf8("+"))
		spacer = QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)

		self.vitesseSlider.setOrientation(Qt.Horizontal)
		self.vitesseSlider.setRange(1, 30)

		self.vitesseSlider.setToolTip(self.trUtf8("Choix de la vitesse de défilement automatique des étapes"))

		# Attachement du bouton au formulaire
		vitesse.addWidget(vitesseMoins)
		vitesse.addWidget(self.vitesseSlider)
		vitesse.addWidget(vitessePlus)
		vitesse.addSpacerItem(spacer)
		groupeVitesse.setLayout(vitesse)
		self.formulaire.addRow(self.trUtf8("Vitesse"), groupeVitesse)


	# Création des boutons de défilement et de la génération aléatoire globale
	def setEtapes(self) :
		etapes = QHBoxLayout()
		numEtapeLabel = QLabel(self.trUtf8("Etape"))
		self.numEtape = QSpinBox() # Numéro de l'étape courante, étape précédente/suivante, saut vers une étape
		self.playArriere = QPushButton(self.trUtf8("<")) # Défilement automatique arrière
		self.pause = QPushButton(self.trUtf8("||")) # Pause
		self.playAvant = QPushButton(self.trUtf8(">")) # Défilement automatique avant
		self.gen = QPushButton(self.trUtf8("Générer")) # Génération aléatoire globale

		self.numEtape.setMaximum(10000)
		self.numEtape.setKeyboardTracking(False) # pour éviter qu'un signal ne soit émis avant que l'utilisateur ait validé (Entrée) son choix

		self.numEtape.setToolTip(self.trUtf8("Numéro de l'étape courante\nEntrer un numéro d'étape et valider (touche Entrée) pour y sauter"))
		self.playArriere.setToolTip(self.trUtf8("Lance le défilement automatique des étapes vers l'arrière"))
		self.pause.setToolTip(self.trUtf8("Arrête le défilement automatique des étapes"))
		self.playAvant.setToolTip(self.trUtf8("Lance le défilement automatique des étapes vers l'avant"))
		self.gen.setToolTip(self.trUtf8("Génère des densités (sauf si 'Equilibrée' coché), une grille et des règles aléatoires\nSi un voisinage personnalisé est sélectionné, génère un voisinage aléatoire pour cet état"))

		# Attachement des boutons au formulaire
		etapes.addWidget(numEtapeLabel)
		etapes.addWidget(self.numEtape)
		etapes.addWidget(self.playArriere)
		etapes.addWidget(self.pause)
		etapes.addWidget(self.playAvant)
		etapes.addWidget(self.gen)
		self.fin.addLayout(etapes)

